import type { Ref } from "vue";
import transcodeWorker from "./transcode.worker?worker";
import SynthSound from "./SynthSound";
type StatusType = "play" | "stop" | "init" | "end" | "paused";
let size = 0;
import TTS from "@/plugins/xunfei/xunfeiSound";
class AudioPlayer {
  worker: Worker; // webworker 用户后台合成音频
  audioData: number[]; // 音频数据
  audioContext?: AudioContext; // 因
  audioDataOffset: Ref<number>;
  status: StatusType;
  canvas?: CanvasRenderingContext2D | null;
  bufferSource?: AudioBufferSourceNode;
  synth?: SynthSound;
  tts: TTS;
  constructor() {
    this.worker = new transcodeWorker();
    this.audioData = [];
    this.status = "init";
    try {
      this.synth = new SynthSound();
    } catch {}
    this.tts = new TTS();
    let workerData = {
      onMessage: (e: any) => this.onMessage(e),
    };
    this.audioDataOffset = ref(0);
    this.worker.onmessage = workerData.onMessage.bind(workerData);
    this.audioInit();
  }
  clear() {
    this.audioStop();
    this.audioData = [];
  }
  /**
   *  音频初始化
   */
  audioInit(): AudioContext {
    let AudioContext = window.AudioContext || window.webkitAudioContext;
    if (AudioContext) {
      this.audioContext = new AudioContext();
      this.audioContext.resume();
      this.audioDataOffset.value = 0;
    }
    return this.audioContext!;
  }
  getData() {
    return this.audioData;
  }
  addData(data: Float32Array) {
    this.audioData.push(...data);
  }
  onMessage(e: any) {
    this.addData(e.data.data);
    this.start();
  }
  setStatus(status: StatusType) {
    this.status = status;
  }
  // 音频播放结束
  audioStop() {
    this.setStatus("end");
    if (this.bufferSource) {
      try {
        this.bufferSource.stop();
      } catch (e) {
        // console.log(e)
      }
    }
  }
  /**
   * 重置
   */
  reset() {
    this.audioContext?.resume();
    this.audioStop();
    this.audioData = [];
    this.audioDataOffset.value = 0;
  }
  /**
   * 开始
   */
  onstart() {
    this.audioContext!.resume();
  }
  /**
   * 暂停
   */
  onpaused() {
    this.setStatus("paused");
    this.audioContext!.suspend();
  }
  /**
   * 开始
   * @returns
   */
  start() {
    if (this.audioData.length) {
      this.audioPlay();
    } else {
      if (!this.audioContext) {
        this.audioInit();
      }
      if (!this.audioContext) {
        alert("该浏览器不支持webAudioApi相关接口");
        return;
      }
    }
  }
  /**
   * 停止
   */
  stop() {
    this.audioStop();
  }

  /**
   * 自动播放
   */
  async audioPlay() {
    let audioContext = this.audioContext;
    if (!audioContext) {
      audioContext = this.audioInit();
    }
    if (this.status == "play") return;
    this.setStatus("play");
    let audioData = this.audioData.slice(this.audioDataOffset.value);
    console.log(this.audioDataOffset.value);
    this.audioDataOffset.value += audioData.length;
    let audioBuffer = audioContext.createBuffer(1, audioData.length, 22050);
    let nowBuffering = audioBuffer.getChannelData(0);
    if (audioBuffer.copyToChannel) {
      audioBuffer.copyToChannel(new Float32Array(audioData), 0, 0);
    } else {
      for (let i = 0; i < audioData.length; i++) {
        nowBuffering[i] = audioData[i];
      }
    }
    let bufferSource = audioContext.createBufferSource();
    this.bufferSource = bufferSource;
    bufferSource.buffer = audioBuffer;
    bufferSource.connect(audioContext.destination);
    bufferSource.start();
    console.log("");

    bufferSource.onended = (event) => {
      if (this.status !== "play") {
        return;
      }
      if (this.audioDataOffset.value < this.audioData.length) {
        this.setStatus("stop");
        console.log("结束");
        this.audioPlay();
      } else {
        this.setStatus("stop");

        this.audioStop();
      }
    };
  }
  postMessage(str: string | string[], isLast: boolean = true) {
    this.worker.postMessage(str);
  }
  send(msg: string) {
    if (this.synth) {
      this.synth?.speak(msg);
    } else {
      this.tts.send(msg).then((res) => {
        res.forEach((item) => {
          this.postMessage(item);
        });
      });
    }
  }
}

export { AudioPlayer as default };
